// ========================================================================
// = Licensing Babble                                                     =
// ========================================================================
// The MIT License
// 
// Copyright (c) 2007 Brian Anderson (banderson623@gmail.com)
// 
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// 
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

// =========================================================================
// = Introduction / Read Me                                                =
// =========================================================================
// 
//      A simple javascript library to help you warm the 
//          browser's cache for the following pages.
// 
// Maybe this should have been called the asset post loader?
// Given an array it will go ahead and an attach a listener to the DOM,
// once the DOM is loaded, it will fire off a request to continue to load 
// other assets... this is to warm the cache for the following pages, 
// so they load faster.

// =========================================================================
// = Configuration                                                         =
// =========================================================================
// There are a couple of configurations to set, all of which are optional.
// 
//  delayBefore    (number) seconds to wait before starting the loading process
// 
//  delayBetween   (number) seconds to wait between requests
// 
//  onComplete     (function) this function will get executed once the entire
//                            array of assets is requested, it will receive
//                            the initial array as it's argument.
// 
//  afterEach      (function) this function will get executed after each 
//                            assets is requested, it will receive
//                            the asset URL as the argument
//                 
//  debug          (boolean) true will print what its doing to console.log()
//                           thats firebug's logger (www.getfirebug.com)


// =========================================================================
// = Simple Example                                                        =
// =========================================================================
// Somewhere in your html include the following:
//    <script type="text/javascript" charset="utf-8">
//      new AssetPreLoader(['http://www.google.com/doodle13.html']);
//    </script>

// ==========================================================================
// = More Complex Example                                                   =
// ==========================================================================
// <script type="text/javascript" charset="utf-8">
//  var loadplease = [
//    'local_test.png',
//    'http://www.google.com/logos/holiday07_3.gif',
//  ];
// 
//  afterwards = function(loaded){
//    loaded.each(function(l){
//      $('div_to_insert_images').insert('<img src="' + l + '"/>');
//    });
//  }
// 
//  
//  new AssetPreLoader(loadplease, {delayBefore:  2.0,
//                                  delayBetween: 1.0, 
//                                  onComplete: afterwards,
//                                  });
//  
// </script>

// ==========================================================================
// = Requirements                                                           =
// ==========================================================================
// Prototype 1.6, 
//    available: http://prototypejs.org/download

var AssetPreLoader = Class.create({
  config: function(){
    // NOTE: these settings can be overriden per instance, 
    // via passing a second argument to the constructor.
    
    // Seconds to wait after DOM is loaded
    // before beginning to load assets
    this.delay_before =  0.5;
    // Seconds to wait between asset loads
    // This is safe to set to any number down to 10ms, 
    // it will not run over itself as each asset is loaded, 
    //   then the next one will be loaded.
    this.delay_between = 0.1; 
    
    // When true it will use console.log to try to add some 
    // notices, about whats going on.
    this.debug_enabled = false;
    
    // You can give this a function to do when its all done
    this.on_complete = function(){};
    
    // 
    this.after_each = function(){};
  },
  
// ==========================================================================================
// = Don't modify anything after this line, all the configurable-things are above this line =
// ==========================================================================================
  
  initialize: function(array_to_load, options){
    this.config();
    
    this.applyOptions(options);
    
    this.payload = array_to_load; 
    
    this.addListenerToWindow();
    this.loading = null;  //used to store what is currently loading
    this.loaded = [];     // holds the loaded assets URL's
  },
  
  start: function(){
    this.debug('Start fired. Assets to load: ' + this.payload.length + " >> " + this.payload.inspect());
    var bound_do_load =   this.doLoad.bind(this);
    var bound_call_back = this.doCallBack.bind(this);
    
    new PeriodicalExecuter(function(pe) {
      if(!bound_do_load()){
        pe.stop();
        bound_call_back();
      }
    }, this.delay_between);
  },
  
  doLoad: function(){
    this.loading = new Image;
		this.loading.src = this.payload.shift();
		this.loaded.push(this.loading.src)
    this.debug('Loading: ' + this.loading.src);
    this.doAfterEach(this.loading.src);
    return (this.payload.length > 0);
  },
  
  doCallBack: function(){
    this.debug('doing callback: ' + this.on_complete);
    // this.debug('with argument:' + this.loaded);
    this.on_complete(this.loaded);
  },
  
  doAfterEach: function(src){
    if(Object.isFunction(this.after_each)) {
      this.debug('executing after each callback');
      this.after_each(src);
    }
  },
  
  applyOptions: function(option_hash){
    opt = new Hash(option_hash);

    this.debug(opt.inspect());
    if(!Object.isUndefined(opt.get('onComplete')))    this.on_complete =   opt.unset('onComplete');
    if(!Object.isUndefined(opt.get('debug')))         this.debug_enabled = opt.unset('debug');
    if(!Object.isUndefined(opt.get('delayBetween')))  this.delay_between = opt.unset('delayBetween');
    if(!Object.isUndefined(opt.get('delayBefore')))   this.delay_before =  opt.unset('delayBefore');
    if(!Object.isUndefined(opt.get('afterEach')))     this.after_each =    opt.unset('afterEach');
    
  },
  
  debug: function(txt){
    if (this.debug_enabled == true){
     try {
       console.log(txt);
     } catch(err){}
    }
  },
  
  addListenerToWindow: function(){
    // Element.delay(this.initial_delay_in_seconds,function(){})
    var start_me = this.start.bind(this);
    var delay = this.delay_before * 1000;
    Event.observe(window, 'load', function(){
      window.setTimeout(function(){start_me();},delay);
    });    
  },
		
	
});